﻿
//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////

#include "CmdGStyleModuleEntry.h"
#include "IControl.h"
#include "IPickTarget.h"
#include "IRibbonGroup.h"
#include "IGroupHandler.h"
#include "GcmpCommandState.h"
#include "IComboBoxDefinition.h"
#include "ICheckBoxGroupHandler.h"
#include "ICheckBoxGroupEventArgs.h"
#include "ICommandButtonDefinition.h"
#include "ICheckBoxGroupDefinition.h"

#include "UiBuilder.h"
#include "GRepCommandIds.h"
#include "CommandRegister.h"
#include "SampleUIUtils.h"
#include "EnableCompileWarning_The_LAST_IncludeInCpp.h" 

/// 本文件是界面实现的辅助类，不包含GDMP API的演示内容

using namespace Sample;
using namespace gcmp;

#pragma  region CmdGStyleHelp
REGISTER_COMMAND(CmdGStyleHelp)

CmdGStyleHelp::CmdGStyleHelp() : CommandBase(ID_CMD_GSTYLE_HELP) {}
CmdGStyleHelp::~CmdGStyleHelp() {}

gcmp::OwnerPtr<gcmp::IAction> CmdGStyleHelp::ExecuteCommand(const gcmp::CommandParameters& cmdParams)
{
    ShellExecute(NULL, L"open", L"https://developer.glodon.com/docs/gdmp/24.0.0305.0/cppdev/g55y7320", NULL, NULL, SW_SHOWNORMAL);
    return nullptr;
}

bool CmdGStyleHelp::IsEnabled() const
{
    return GcmpCommandState::IsInDocumentEnvironment();
}

bool CmdGStyleHelp::IsVisible() const
{
    return GcmpCommandState::IsInDocumentEnvironment();
}
#pragma endregion

#pragma region 各种Ribbon控件的状态控制
// 整个显示样式模块Ribbon可见性控制
class GStyleGroupHandler : public IGroupHandler
{
public:
    virtual bool IsVisible() const override
    {
        return GcmpCommandState::IsInDocumentEnvironment();
    }
};

class PickCheckBoxGroupHandler : public ICheckBoxGroupHandler
{
public:
    virtual bool IsVisible(const std::wstring& id) const override
    {
        return GcmpCommandState::IsInDocumentEnvironment();
    }

    virtual bool IsEnabled(const std::wstring& id) const override
    {
        return GcmpCommandState::IsInDocumentEnvironment();
    }

    virtual void On(ICheckBoxGroupEventArgs* pArgs) override
    {
    }
};
#pragma endregion 各种Ribbon控件的状态控制

#pragma region CmdGStyleModuleEntry

REGISTER_COMMAND(CmdGStyleModuleEntry)

CmdGStyleModuleEntry::CmdGStyleModuleEntry()
    : CommandBase(ID_CMD_GSTYLE_ENTRY)
{}

CmdGStyleModuleEntry::~CmdGStyleModuleEntry(){}

bool CmdGStyleModuleEntry::IsEnabled() const
{
    return GcmpCommandState::IsInDocumentEnvironment();
}

bool CmdGStyleModuleEntry::IsVisible() const
{
    return GcmpCommandState::IsInDocumentEnvironment();
}

IRibbonGroup* Sample::CmdGStyleModuleEntry::GetRibbonGroup()
{
    ModuleUIUtils* pModuleUIUtils = ModuleUIUtils::Get();
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pModuleUIUtils, L"pModuleUIUtils为空",L"GDMP",L"2024-03-30");
    return SampleUIUtils::FindGroup(ID_PAGE_MODULE, ID_GROUP_MODULE_PICK_CONTEXT);
}

const bool Sample::CmdGStyleModuleEntry::GetCheckboxValue(std::wstring checkboxId)
{
    if (IRibbonGroup* pRibbonGroup = GetRibbonGroup())
    {
        IControl* pControl = pRibbonGroup->GetControl(ID_GSTYLE_PICKER_GROUP);
        DBG_WARN_AND_RETURN_FALSE_UNLESS(pControl, L"pControl为空",L"GDMP",L"2024-03-30");
        ICheckBoxGroupDefinition* pCheckBoxGroupDefinition = dynamic_cast<ICheckBoxGroupDefinition*>(pControl->GetControlDefinition());
        DBG_WARN_AND_RETURN_FALSE_UNLESS(pCheckBoxGroupDefinition, L"pCheckBoxGroupDefinition为空",L"GDMP",L"2024-03-30");
        bool ok;
        return pCheckBoxGroupDefinition->GetCheckState(checkboxId, &ok) == CheckState::Checked;
    }
    return false;
}

void Sample::CmdGStyleModuleEntry::SetPickTarget(gcmp::IPickTarget * pPickTarget)
{
    pPickTarget->DisableAll();

    if (GetCheckboxValue(ID_GSTYLE_PICKER_FILTER_EnableFace))                   { pPickTarget->EnableFace(); };
    if (GetCheckboxValue(ID_GSTYLE_PICKER_FILTER_EnableEdge))                   { pPickTarget->EnableEdge(); };
    if (GetCheckboxValue(ID_GSTYLE_PICKER_FILTER_EnableCurve))                  { pPickTarget->EnableCurve(); };
    if (GetCheckboxValue(ID_GSTYLE_PICKER_FILTER_EnableText))                   { pPickTarget->EnableText(); };
    if (GetCheckboxValue(ID_GSTYLE_PICKER_FILTER_EnableMeshTriangle))           { pPickTarget->EnableMeshTriangle(); };
    if (GetCheckboxValue(ID_GSTYLE_PICKER_FILTER_EnableSegmentOfPolyCurve3d))   { pPickTarget->EnableSegmentOfPolyCurve3d(); };
    if (GetCheckboxValue(ID_GSTYLE_PICKER_FILTER_EnableSegmentOfPolyCurve))     { pPickTarget->EnableSegmentOfPolyCurve(); };
    if (GetCheckboxValue(ID_GSTYLE_PICKER_FILTER_EnableGRep)) { pPickTarget->EnableGraphicsElementShape(); };
    if (GetCheckboxValue(ID_GSTYLE_PICKER_FILTER_EnablePoint)) { pPickTarget->EnablePoint(); };
}

OwnerPtr<IAction> CmdGStyleModuleEntry::ExecuteCommand(const CommandParameters& cmdParams)
{
    ModuleUIUtils::Get()->RemoveModuleUI();
    UiBuilder::CleanContextUI();

    if (GetRibbonGroup())
    {
        return nullptr;
    }

    std::wstring groupName = L"显示样式模块示例";

    OwnerPtr<IRibbonGroup> opGStyleGroup = IRibbonGroup::Create(ID_GROUP_MODULE_PICK_CONTEXT, GBMP_TR(groupName));
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opGStyleGroup, L"opGStyleGroup为空",L"GDMP",L"2024-03-30");
    opGStyleGroup->SetGroupHandler(NEW_AS_OWNER_PTR(GStyleGroupHandler));
    {
        OwnerPtr<ICommandButtonDefinition> opButtonDef = 
            ICommandButtonDefinition::Create(ID_CMD_GSTYLE_VIEWER, L"显示样式探针", 
                L"演示如何修改选中图形节点/图元/类别的各层级显示样式重载方式。启动命令后拾取图形节点，可以在右侧的checkbox中过滤图形节点。如果选择的图形节点是视图图形节点，则不能直接修改图形节点的样式（表格中的最后一行）", 
                ID_CMD_GSTYLE_VIEWER, L":/images/Module/GStyle/样式重载.png");
        opGStyleGroup->AddButton(TransferOwnership(opButtonDef));
    }
    {
        OwnerPtr<ICheckBoxGroupDefinition> opCheckBoxGroup = ICheckBoxGroupDefinition::Create(ID_GSTYLE_PICKER_GROUP, L"PickCheckBoxGroup");
        opCheckBoxGroup->AddCheckBox(ID_GSTYLE_PICKER_FILTER_EnableFace, L"面", L"Face", CheckState::Checked);
        opCheckBoxGroup->AddCheckBox(ID_GSTYLE_PICKER_FILTER_EnableEdge, L"边", L"Edge", CheckState::Checked);
        opCheckBoxGroup->AddCheckBox(ID_GSTYLE_PICKER_FILTER_EnablePoint, L"点", L"SubNodeOfZoomFree", CheckState::Checked);
        opCheckBoxGroup->AddCheckBox(ID_GSTYLE_PICKER_FILTER_EnableCurve, L"曲线", L"Curve", CheckState::Checked);
        opCheckBoxGroup->AddCheckBox(ID_GSTYLE_PICKER_FILTER_EnableText, L"文字", L"Text", CheckState::Checked);
        opCheckBoxGroup->AddCheckBox(ID_GSTYLE_PICKER_FILTER_EnableMeshTriangle, L"Mesh", L"MeshTriangle", CheckState::Checked);
        opCheckBoxGroup->AddCheckBox(ID_GSTYLE_PICKER_FILTER_EnableSegmentOfPolyCurve3d, L"多段线的线", L"SegmentOfPolyCurve3d", CheckState::Checked);
        opCheckBoxGroup->AddCheckBox(ID_GSTYLE_PICKER_FILTER_EnableSegmentOfPolyCurve, L"二维多段线的线", L"SegmentOfPolyCurve", CheckState::Checked);
        opCheckBoxGroup->AddCheckBox(ID_GSTYLE_PICKER_FILTER_EnableGRep, L"图元", L"GraphicsElementShape", CheckState::Checked);
        opCheckBoxGroup->SetControlHandler(TransferOwnership(NEW_AS_OWNER_PTR(PickCheckBoxGroupHandler)));
        opGStyleGroup->AddCheckBoxGroup(TransferOwnership(opCheckBoxGroup));
    }

    {
        OwnerPtr<ICommandButtonDefinition> opButtonDef =
            ICommandButtonDefinition::Create(ID_CMD_GSTYLE_VIEWER_TREE, L"节点树样式探针",
                L"演示如何修改GRep探针浏览器选中图形节点/图元/类别的各层级显示样式重载方式。首先运行【模型图形表达探针】，在探针浏览器中选择一个图形节点，然后运行该命令。在这种方式下只有GRep探针浏览器可以修改的图元才能直接修改图形节点的显示样式。", 
                ID_CMD_GSTYLE_VIEWER_TREE, L":/images/Module/GStyle/样式重载节点.png");
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opButtonDef, L"opButtonDef为空",L"GDMP",L"2024-03-30");
        opGStyleGroup->AddButton(TransferOwnership(opButtonDef));
    }

    {
        OwnerPtr<ICommandButtonDefinition> opGrepProbeButtonDefinition =
            ICommandButtonDefinition::Create(ID_CMD_GREP_PROBE, GBMP_TR(L"模型图形表达探针"),
                GBMP_TR(L"读取选择图元的模型图形表达。如果选择图元为IDirectShape或IPureGraphicsElement，那么可以修改图元的模型图形表达；其他类型图元可以用“复制GRep为可编辑”生成可修改的IDirectShape或IPureGraphicsElement"),
                ID_CMD_GREP_PROBE, L":/images/Module/Grep/grep_tree.png");
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opGrepProbeButtonDefinition, L"opGrepProbeButtonDefinition为空", L"GDMP", L"2024-03-30");
        opGStyleGroup->AddButton(TransferOwnership(opGrepProbeButtonDefinition));
    }
    {
        OwnerPtr<ICommandButtonDefinition> opTestGStyleButtonDefinition =
            ICommandButtonDefinition::Create(ID_CMD_SCALE_GSTYLE, GBMP_TR(L"视图比例动态样式"),
                GBMP_TR(L"演示如何根据视图比例动态刷新图元的显示样式，该命令需要配合【刷新显示样式】命令。选中图元运行该命令后，在【视图比例】改为大于或小于1:50后，运行【刷新显示样式】命令可以看到有显示样式的改变。"),
                ID_CMD_SCALE_GSTYLE, L":/images/Module/GStyle/缩放样式.png");
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opTestGStyleButtonDefinition, L"opTestGStyleButtonDefinition为空", L"GDMP", L"2024-03-30");
        opGStyleGroup->AddButton(TransferOwnership(opTestGStyleButtonDefinition));
    }
    {
        OwnerPtr<ICommandButtonDefinition> opGRepRefreshDefinition =
            ICommandButtonDefinition::Create(ID_CMD_GREP_REFRESH_GREP, GBMP_TR(L"刷新显示样式"),
                GBMP_TR(L"刷新视图中所有可见图元的显示样式。有些操作显示样式不会被平台更新，需要用户代码调用IModelView::UpdateModelViewGraphicsElementShapes或在图元计算机中更新。"),
                ID_CMD_GREP_REFRESH_GREP, L":/images/Module/Grep/grep-refresh.png");
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opGRepRefreshDefinition, L"opGRepRefreshDefinition为空", L"GDMP", L"2024-03-30");
        opGStyleGroup->AddButton(TransferOwnership(opGRepRefreshDefinition));
    }
    {
        OwnerPtr<ICommandButtonDefinition> opGRepCreateModelDefinition =
            ICommandButtonDefinition::Create(ID_CMD_GREP_CREATE_MODEL, GBMP_TR(L"创建测试模型"),
            GBMP_TR(L"创建包含各种不同性质图形节点和显示样式的图元。"),
                ID_CMD_GREP_CREATE_MODEL, L":/images/Module/Common/model.png");
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opGRepCreateModelDefinition, L"opGRepCreateModelDefinition为空",L"GDMP",L"2024-03-30");
        opGStyleGroup->AddButton(TransferOwnership(opGRepCreateModelDefinition));
    }

    {
        OwnerPtr<ICommandButtonDefinition> opLookAroundDefinition =
            ICommandButtonDefinition::Create(L"CmdLookAround", GBMP_TR(L"旋转视图"),
                GBMP_TR(L"旋转视图。"),
                L"CmdLookAround", L":/images/Module/Common/model.png");
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opLookAroundDefinition, L"opLookAroundDefinition为空", L"GDMP", L"2024-03-30");
        opGStyleGroup->AddButton(TransferOwnership(opLookAroundDefinition));
    }

    {
        OwnerPtr<ICommandButtonDefinition> opSwitchCameraDefinition =
            ICommandButtonDefinition::Create(L"CmdSwitchCamera", GBMP_TR(L"切换相机类型"),
                GBMP_TR(L"切换相机类型。"),
                L"CmdSwitchCamera", L":/images/Module/Common/model.png");
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opSwitchCameraDefinition, L"opSwitchCameraDefinition为空", L"GDMP", L"2024-03-30");
        opGStyleGroup->AddButton(TransferOwnership(opSwitchCameraDefinition));
    }

    OwnerPtr<ICommandButtonDefinition> opHelpDefinition =
        ICommandButtonDefinition::Create(ID_CMD_GSTYLE_HELP, GBMP_TR(L"帮助"), GBMP_TR(L"打开GDMP在线帮助网站"),
            ID_CMD_GSTYLE_HELP, L":/images/Module/Common/Help.png");
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opHelpDefinition, L"opHelpDefinition为空",L"GDMP",L"2024-03-30");
    opGStyleGroup->AddButton(TransferOwnership(opHelpDefinition));

    ModuleUIUtils::Get()->SetupModuleUI(TransferOwnership(opGStyleGroup), groupName);
    return nullptr;
}
#pragma endregion CmdGStyleModuleEntry

